/**
 * Multicast project Bidois Morgan & Thomas Nunes
 *
 */
package middleware;

import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 *
 * @author Morgan Bidois <morgan.bidois@e.ujf-grenoble.fr>
 *
 * the directory regroup all infos of each client of the group
 */
public class Directory {

    private LinkedList<ClientInfos> clientList;

    public Directory() {
        this.clientList = new LinkedList<>();
    }

    public int size() {
        return this.clientList.size();
    }

    /**
     * get the number of clients alive
     *
     * @return the number of clients alive
     */
    public int sizeAliveClient() {
        int total = 0;
        for (ClientInfos ci : clientList) {
            if (ci.getState() == 1) {
                total++;
            }
        }
        return total;
    }

    public void addClient(ClientInfos newClient) {
        this.clientList.add(newClient);
    }

    public List<ClientInfos> getClientList() {
        return this.clientList;
    }

    public ClientInfos getClientById(int id) {
        ClientInfos ciToReturn = null;
        for (ClientInfos ci : clientList) {
            if (ci.getIdClient() == id) {
                ciToReturn = ci;
                break;
            }
        }
        return ciToReturn;
    }

    public ClientInfos getClientAt(int index) {
        return this.clientList.get(index);
    }

    /**
     * Serialize directory
     *
     * @return String result.
     */
    public String getDirectoryToSend() {
        String str = "";
        for (ClientInfos ci : this.clientList) {
            str += ci.getClientToSend();
        }
        return str;
    }

    @Override
    public String toString() {
        String str = "";
        for (ClientInfos ci : this.clientList) {
            str += "\n" + ci.toString();
            if (this.clientList.size() != this.clientList.indexOf(ci)) {
                str += "\n----------------";
            }
        }
        return str;
    }

    public int getClientByPort(int port) {
        for (ClientInfos ci : clientList) {
            if (ci.getPort() == port) {
                return ci.getIdClient();
            }
        }
        return -1;
    }

    /**
     * add a new socket to a client
     *
     * @param socket
     * @return if the port correspoding to a client
     */
    public boolean addSocket(SocketChannel socket) {
        int port = socket.socket().getPort();
        for (ClientInfos ci : clientList) {
//            System.out.println("port= " + ci.getPort() + "   Port2add:" + port);
            if (ci.getPort() == port) {
                ci.setSocketChannel(socket);
                return true;
            }
        }
        return false;
    }

    /**
     * notify that a client is dead, set his state to 0.
     *
     * @param afkClientId the id of the dead client
     */
    void notifyClientLeave(int afkClientId) {
        this.getClientById(afkClientId).setState(0);
    }

    /**
     * Test if the name exist in the directory
     *
     * @param name
     * @return
     */
    boolean isNameExist(String name) {
        for (ClientInfos ci : clientList) {
            if (ci.getName().equals(name)) {
                return true;
            }
        }
        return false;
    }

    String getAllClientName() {
        String res = "Les clients présent:\n";

        for (ClientInfos ci : clientList) {
            if (ci.getName() != null) {
                res += "-" + ci.getName() + "\n";
            }
        }
        return res + "\n";
    }
}
